package com.bifrost.task;

import com.bifrost.cbentity.SapStoreProduct;
import com.bifrost.cbrepository.SapStoreProductRepository;
import com.bifrost.constant.OrderStatus;
import com.bifrost.constant.OrderStatusHistoryOrderType;
import com.bifrost.entity.*;
import com.bifrost.exception.SendRecordException;
import com.bifrost.mtRepository.MtOrderRecordRepository;
import com.bifrost.mtentity.MtOrderRecord;
import com.bifrost.repository.*;
import com.google.common.collect.Maps;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.handler.annotation.JobHandler;
import com.xxl.job.core.log.XxlJobLogger;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 *   把订单已支付和退单记录到中间库
 *  @Author:Sophia
 *  @Date:2018/7/12
 *  
 */
@Component
@JobHandler(value="autoOrderRecordTask")
@Slf4j(topic = "JOB")
public class AutoOrderRecordTask extends IJobHandler {
    private static final long LOCKED_TIME=60*5;
    @Autowired
    RedissonClient redisson;

    @Autowired
    OrderRepository orderRepository;
    @Autowired
    OrderItemRepository orderItemRepository;
    @Autowired
    OrderReturnRepository orderReturnRepository;
    @Autowired
    OrderReturnItemRepository orderReturnItemRepository;
    @Autowired
    MtOrderRecordRepository mtOrderRecordRepository;
    @Autowired
    TransactionSendLogRepository transactionSendLogRepository;
    @Autowired
    SapStoreGoodsRepository sapStoreGoodsRepository;
    @Autowired
    OrderStatusHistoryRepository statusHistoryRepository;
    @Autowired
    SapStoreProductRepository sapStoreProductRepository;


    @Override
    public ReturnT<String> execute(String s) throws Exception {
        //同步订单
        XxlJobLogger.log("经销商品发送富基开始");
        sysOrder();
        XxlJobLogger.log("经销商品发送富基完成");
        return ReturnT.SUCCESS;
    }


    /**
     * 同步订单
     */
    public void sysOrder() {
        RLock lock = redisson.getLock(TransactionSendLog.LOCK_KEY);
        try{
            boolean locked =  lock.tryLock(LOCKED_TIME,TimeUnit.SECONDS);
            if(locked){
                //查找所有发生交易和库存变化的SALES OR REFUND订单且同步状态为0或null
                List<TransactionSendLog> orders = transactionSendLogRepository.findByTypeAndSendRecordStatus();
                if(orders.isEmpty()){
                    return;
                }
                //满足条件的订单 add
                Set<Long> transIds=new HashSet();
                //不相关数据
                HashMap<Long, String> noRecordMap = Maps.newHashMap();
                //符合条件的订单add到records
                List<MtOrderRecord> records=new ArrayList<>();

                for (int i=0;i<orders.size();i++){
                    try {
                        if (TransactionSendLog.Type.REFUND.equals(orders.get(i).getType())){
                            if (orders.get(i).getOrderId()!=null) {
                                OrderReturn orderReturn = orderReturnRepository.findOne(orders.get(i).getOrderId());
                                //判断订单编号是否为空
                                if (orderReturn == null) {
                                    log.warn(String.format("同步失败： 交易%s  退单Id: %s  信息:%s", orders.get(i).getId(), orderReturn.getReturnNumber(), "退单不存在"));
                                    continue;
                                }
                                //根据订单查找订单明细
                                List<OrderReturnItem> orderReturnItems = orderReturnItemRepository.findByOrderReturn(orderReturn);
                                if (CollectionUtils.isNotEmpty(orderReturnItems)){
                                    for (int j = 0; j < orderReturnItems.size(); j++) {
                                        //根据sap编号查找商品是否是经销商品
                                        SapStoreGoods storeGoods = sapStoreGoodsRepository.findFirstByMatnrAndLocnr(orderReturnItems.get(j).getExternalId(), orderReturn.getMerchantStore().getExternalId());
                                        if(storeGoods==null){
                                            storeGoods=sapStoreGoodsRepository.findFirstByMatnr(orderReturnItems.get(j).getExternalId());
                                            if(storeGoods==null){
                                                SapStoreProduct product =sapStoreProductRepository.findFirstByMatnr(orderReturnItems.get(j).getExternalId());
                                                if(product==null){
                                                    throw new SendRecordException(String.format("交易%s订单id:%s商品编码%s门店%s找不到商品的寄售控制信息",orders.get(i).getId(),orderReturn.getReturnNumber(), orderReturnItems.get(j).getExternalId(),orderReturn.getMerchantStore().getExternalId()));
                                                }else{
                                                    BeanUtils.copyProperties(product,storeGoods=new SapStoreGoods());
                                                }
                                            }
                                        }
                                        if (StringUtils.isNotBlank(storeGoods.getConsProcg())) {
                                            log.warn("忽略交易Id: {}  退单Id: {}  商品sap编码:{} 信息:{}", orders.get(i).getId(),orderReturn.getReturnNumber(), orderReturnItems.get(j).getExternalId(), "该商品不是经销商品");
                                        }else{
                                            //判断商品是否已存在与中间库
                                            MtOrderRecord mtOrderRecord = mtOrderRecordRepository.findByOrderNumberAndExternalIdAndOrderType(orderReturn.getReturnNumber(), orderReturnItems.get(j).getExternalId(),orders.get(i).getType().toString());
                                            if (mtOrderRecord != null) {
                                                log.warn("忽略交易Id:{}  退单Id: {}  商品sap编码:{} 信息:{}", orders.get(i).getId(),orderReturn.getReturnNumber(), orderReturnItems.get(j).getExternalId(), "中间库订单已存在");
                                            }else{
                                                mtOrderRecord = new MtOrderRecord();
                                                mtOrderRecord.setOrderNumber(orders.get(i).getTransNumber());
                                                mtOrderRecord.setExternalId(orderReturnItems.get(j).getExternalId());
                                                mtOrderRecord.setStoreCode(orderReturn.getMerchantStore().getExternalId());
                                                mtOrderRecord.setBuyNumber(orderReturnItems.get(j).getSkuQuantity().longValue());
                                                mtOrderRecord.setSellPrice(orderReturnItems.get(j).getSkuPrice().doubleValue());
                                                mtOrderRecord.setDeliveryTime(orderReturn.getUpdatedTimestamp().toString());
                                                mtOrderRecord.setOrderType(TransactionSendLog.Type.REFUND.toString());
                                                records.add(mtOrderRecord);
                                            }
                                        }
                                    }
                                    transIds.add(orders.get(i).getId());
                                }
                            }
                        }else if(TransactionSendLog.Type.SALES.equals(orders.get(i).getType())){
                            if (orders.get(i).getOrderId()!=null){
                                Order order=orderRepository.findOne(orders.get(i).getOrderId());
                                //判断订单编号是否为空
                                if (order==null){
                                    log.warn(String.format("同步失败，交易%s  订单Id: %s  错误信息:%s", orders.get(i).getId(),order.getOrderNumber(), "销售订单不存在"));
                                    continue;
                                }
                                //订单编号不为空 判断它的订单状态是否是已发货状态SHIPPED OR FINISHED
                                if (OrderStatus.SHIPPED.equalsIgnoreCase(order.getOrderStatus())||OrderStatus.FINISHED.equalsIgnoreCase(order.getOrderStatus())){
                                    //根据订单查找订单明细
                                    List<OrderItem> orderItems = orderItemRepository.findByOrder(order);
                                    if (CollectionUtils.isNotEmpty(orderItems)){
                                        for (int j=0;j<orderItems.size();j++){
                                            //根据sap编号查找商品是否是经销商品
                                            SapStoreGoods storeGoods=sapStoreGoodsRepository.findFirstByMatnrAndLocnr(orderItems.get(j).getExternalId(),order.getMerchantStore().getExternalId());
                                            if(storeGoods==null){
                                                storeGoods = sapStoreGoodsRepository.findFirstByMatnr(orderItems.get(j).getExternalId());
                                                if(storeGoods==null){
                                                    SapStoreProduct product = sapStoreProductRepository.findFirstByMatnr(orderItems.get(j).getExternalId());
                                                    if(product==null){
                                                        throw new SendRecordException(String.format("交易%s订单id:%s商品编码%s门店%s找不到商品的寄售控制信息",orders.get(i).getId(),order.getOrderNumber(),orderItems.get(j).getExternalId(),order.getMerchantStore().getExternalId()));
                                                    }else {
                                                        BeanUtils.copyProperties(product,storeGoods=new SapStoreGoods());
                                                    }
                                                }
                                            }
                                            if (StringUtils.isNotBlank(storeGoods.getConsProcg())){
                                                log.warn(" 忽略交易{}  订单Id: {}  商品sap编码:{} 信息:{}", orders.get(i).getId(),order.getOrderNumber(),orderItems.get(j).getExternalId(), "该商品不是经销商品");
                                            }else{
                                                //判断商品是否已存在与中间库
                                                MtOrderRecord mtOrderRecord=mtOrderRecordRepository.findByOrderNumberAndExternalIdAndOrderType(order.getOrderNumber(),orderItems.get(j).getExternalId(),orders.get(i).getType().toString());
                                                if (mtOrderRecord!=null){
                                                    log.warn("忽略交易{}  订单Id: {}  商品sap编码:{} 信息:{}", orders.get(i).getId(),order.getOrderNumber(),orderItems.get(j).getExternalId(), "中间库订单已存在");
                                                }else{
                                                    Date deliveryTime = statusHistoryRepository.getShippedTime(order.getOrderId(), OrderStatusHistoryOrderType.ORDER);
                                                    mtOrderRecord = new MtOrderRecord();
                                                    mtOrderRecord.setOrderNumber(orders.get(i).getTransNumber());
                                                    mtOrderRecord.setExternalId(orderItems.get(j).getExternalId());
                                                    mtOrderRecord.setStoreCode(order.getMerchantStore().getExternalId());
                                                    mtOrderRecord.setBuyNumber(orderItems.get(j).getSkuQuantity().longValue());
                                                    mtOrderRecord.setSellPrice(orderItems.get(j).getSkuPrice().doubleValue());
                                                    mtOrderRecord.setDeliveryTime(deliveryTime==null?order.getCreatedTimestamp().toString():deliveryTime.toString());
                                                    mtOrderRecord.setOrderType(TransactionSendLog.Type.SALES.toString());
                                                    records.add(mtOrderRecord);
                                                }
                                            }
                                        }
                                        transIds.add(orders.get(i).getId());
                                    }
                                }else if(OrderStatus.CANCELED.equalsIgnoreCase(order.getOrderStatus())){
                                    transIds.add(orders.get(i).getId());
                                }
                                else {
                                    log.warn(String.format("同步失败,忽略交易%s  订单Id: %s  信息:%s",orders.get(i).getId(),order.getOrderNumber(), "销售单号不是已发货状态"));
                                }
                            }
                        }else if(TransactionSendLog.Type.CANCEL.equals(orders.get(i).getType())){
                            transIds.add(orders.get(i).getId());
                        }
                    } catch (SendRecordException e) {
                        log.error(e.getMessage());
                        noRecordMap.put(orders.get(i).getId(),e.getMessage());
                    }
                }

                //批量插入数据
                try {
                    AutoOrderRecordTask task = (AutoOrderRecordTask) AopContext.currentProxy();
                    task.execute(records,transIds,noRecordMap);
                } catch (Exception e) {
                    log.warn("订单同步失败： 错误信息:{}", e.getMessage());
                }

            }else{
                log.warn("未获取到锁");
            }
        }catch (Exception e){
           log.error(e.getMessage());
           throw new RuntimeException(e);
        }finally {
            if (lock.isLocked()&&lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void execute(List<MtOrderRecord> records, Set<Long> transIds, HashMap<Long, String> noRecordMap) {
        if (CollectionUtils.isNotEmpty(records)){
            mtOrderRecordRepository.save(records);
        }
        //批量更新数据库状态
        if (CollectionUtils.isNotEmpty(transIds)){
            transactionSendLogRepository.batchUpdateSysStatus(transIds,"Y");
        }
        //记录异常数据
        if (!noRecordMap.isEmpty()){
            noRecordMap.entrySet().stream().forEach(entry -> {
                transactionSendLogRepository.singleUpdateSysStatus(entry.getKey(),entry.getValue(),"P");
            });
        }
    }
}
